//
//  DAnalysisDatesViewController.swift
//  Drop
//
//  Created by hushaohua on 2018/5/16.
//  Copyright © 2018年 init. All rights reserved.
//

import UIKit

class DAnalysisDatesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    override func loadView() {
        super.loadView();
    }
    var defaultPrefItem:DAnalysisDatePrefItem?;
    override func viewDidLoad() {
        super.viewDidLoad()

        self.configSelectedPrefItem();
        self.view.addSubview(self.tableView);
        self.tableView.dataSource = self;
        self.tableView.delegate = self;
        self.view.backgroundColor = self.tableView.backgroundColor;
        self.configNavi();
    }
    
    func configSelectedPrefItem() {
        self.rowsModel.currentItem = self.defaultPrefItem;
        if (self.defaultPrefItem != nil){
            switch self.defaultPrefItem!.interval {
            case .day:
                self.intervalTypeControl.selectedSegmentIndex = 0;
                self.rowsModel.setDayAsCurrent();
            case .week:
                self.intervalTypeControl.selectedSegmentIndex = 1;
                self.rowsModel.setWeekAsCurrent();
            case .month:
                self.intervalTypeControl.selectedSegmentIndex = 2;
                self.rowsModel.setMonthAsCurrent();
            }
        }
    }
    
    func configNavi() {
        let right = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(done));
        self.navigationItem.titleView = self.intervalTypeControl;
        self.navigationItem.rightBarButtonItem = right;
    }
    
    var doneClosure:((DAnalysisDatePrefItem)->())?;
    @objc func done() {
        if (self.rowsModel.currentItem == nil){
            _ = HUITip.showText("尚未选择时间范围");
            return;
        }
        if (self.doneClosure != nil){
            self.doneClosure!(self.rowsModel.currentItem!);
        }
        self.navigationController?.popViewController(animated: true);
    }
    
    lazy var pickedLabel:UILabel = {
        var label:UILabel = UILabel(frame: CGRect(x:0,y:0,width:self.view.bounds.size.width,height:44));
        label.textColor = UIColor.red;
        label.numberOfLines = 0;
        return label;
    }();

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    lazy var intervalTypeControl:UISegmentedControl = {
        var control:UISegmentedControl = UISegmentedControl(items: ["天", "周", "月"])
        control.frame = CGRect(x:0,y:0,width:self.view.bounds.size.width - 160,height:32);
        control.selectedSegmentIndex = 0;
        control.backgroundColor = UIColor.white;
        control.tintColor = UIColor.h_blue();
        control.addTarget(self, action: #selector(intervalChanged(_:)), for: .valueChanged);
        return control;
    }();
    
    @objc func intervalChanged(_ control:UISegmentedControl){
        switch control.selectedSegmentIndex {
        case 0:
            self.rowsModel.setDayAsCurrent();
        case 1:
            self.rowsModel.setWeekAsCurrent();
        case 2:
            self.rowsModel.setMonthAsCurrent();
        default:
            break;
        }
        self.tableView.reloadData();
    }
    
    lazy var tableView:UITableView = {
        var tableView:UITableView = UITableView(frame: CGRect(x:0,y:64,width:self.view.bounds.width, height:self.view.bounds.height - 84), style: .grouped);
        tableView.contentInset = UIEdgeInsetsMake(0, 0, 84, 0);        
        tableView.rowHeight = UITableViewAutomaticDimension;
        tableView.estimatedRowHeight = 44;
        tableView.showsVerticalScrollIndicator = false;
        tableView.register(DAnalysisDateTableViewCell.self, forCellReuseIdentifier: "Cell");
        tableView.register(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: "Header");
        tableView.register(UITableViewHeaderFooterView.self, forHeaderFooterViewReuseIdentifier: "Footer");
        return tableView;
    }();
    
    lazy var rowsModel:DAnalysisDateRowsModel = {
        var model:DAnalysisDateRowsModel = DAnalysisDateRowsModel();
        return model;
    }();
    
    var calendarDayModel:DEveryXDaysModel?;
    func everyXDaysPredicate() -> NSPredicate? {
        if self.calendarDayModel != nil {
            if self.calendarDayModel!.isCurrentWeekdays() {
                if self.calendarDayModel!.selectedItems.count != 7 {
                    let predicate = NSPredicate(format: "weekday in %@", self.calendarDayModel!.selectedDays());
                    return predicate;
                }
            }else{
                if self.calendarDayModel!.selectedItems.count != 31 {
                    let predicate = NSPredicate(format: "day in %@", self.calendarDayModel!.selectedDays());
                    return predicate;
                }
            }
        }
        return nil;
    }
    func gotoWeekDay(item:DAnalysisDatePrefItem) {
        let controller:DEveryXDaysViewController = DEveryXDaysViewController();
        weak var weakSelf = self;
        if (self.calendarDayModel != nil && ((self.calendarDayModel!.isCurrentWeekdays() && item.isEveryWeekday) || (self.calendarDayModel!.isCurrentMonthdays() && !item.isEveryWeekday))){
            controller.dataModel = self.calendarDayModel!;
        }
        controller.modalPresentationStyle = .overCurrentContext;
        controller.didGetCalendarDay = { string, model in
            weakSelf?.calendarDayModel = model;
            weakSelf?.rowsModel.currentItem = item;
            item.datePredicate = weakSelf?.everyXDaysPredicate();
            if (item.isEveryWeekday){
                item.detail = "每周 " + string;
            }else{
                item.detail = "每月 " + string + " 日";
            }
            weakSelf?.tableView.reloadData();
        }
        if (item.isEveryWeekday){
            controller.startWeekDays();
        }else{
            controller.startMonthDays();
        }
        self.parent!.present(controller, animated: false, completion: nil);
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return self.rowsModel.numberOfSection();
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.rowsModel.rowsInSection(section);
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return self.rowsModel.sectionAt(section).title.count > 0 ? 30 : 20;
    }
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: "Header");
        let item:DAnalysisDatePrefSection = self.rowsModel.sectionAt(section);
        view?.textLabel?.text = item.title;
        return view;
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 1;
    }
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: "Footer");
        return view;
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension;
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell:DAnalysisDateTableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! DAnalysisDateTableViewCell;
        let section:DAnalysisDatePrefSection = self.rowsModel.sectionAt(indexPath.section);
        let item:DAnalysisDatePrefItem = section.items![indexPath.row];
        cell.titleLabel.text = item.title;
        cell.datesLabel.text = item.detail;
        if (self.rowsModel.currentItem != nil && item == self.rowsModel.currentItem!){
            cell.accessoryType = .checkmark;
            cell.datesLabel.text = self.rowsModel.currentItem!.detail;
        }else{
            cell.accessoryType = .none;
        }
        return cell;
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true);
        
        let section:DAnalysisDatePrefSection = self.rowsModel.sectionAt(indexPath.section);
        let item:DAnalysisDatePrefItem = section.items![indexPath.row];
        
//        if (item.closure != nil){
//            self.rowsModel.currentItem = item;
//            self.tableView.reloadData();
//            item.closure!();
//        }else
        switch item.datePickType {
        case .calendar:
            self.gotoCalendarPicker(item);
        case .everyXDay:
            self.gotoWeekDay(item: item);
        default:
            self.rowsModel.currentItem = item;
            self.tableView.reloadData();
        }
    }
    
    func gotoCalendarPicker(_ item:DAnalysisDatePrefItem){
        let controller = HCalendarViewController();
        controller.calendarTitle = item.title;
        controller.pickedType = item.calenarPickType;
        switch self.intervalTypeControl.selectedSegmentIndex {
        case 0:
            controller.intervalType = .day;
        case 1:
            controller.intervalType = .week;
        case 2:
            controller.intervalType = .month;
        default:
            break;
        }
        weak var weakSelf = self;
        controller.doneClosure = {interval, pick, dates in
            weakSelf?.rowsModel.currentItem = item;
            let result = weakSelf!.calendarPredicateFor(interval: interval, pick: pick, dates: dates);
            item.datePredicate = result.predicate;
            item.detail = result.dateString;
            weakSelf?.tableView.reloadData();
        }
        let back = UIBarButtonItem(title: "", style: .plain, target: self, action: nil);
        self.navigationItem.backBarButtonItem = back;
        self.navigationController?.pushViewController(controller, animated: true);
    }
    
    func calendarPredicateFor(interval:HTimeIntervalType, pick:HCalendarPickType, dates:[DateComponents]) -> (predicate:NSPredicate, dateString:String) {
        switch pick {
        case .unit:
            return self.unitPredicate(dates, interval: interval);
        case .continuous:
            return self.continuousPredicate(dates, interval: interval);
        case .discrete:
            return self.discretePredicate(dates, interval: interval);
        }
    }
    
    func discretePredicate(_ dates:[DateComponents],interval:HTimeIntervalType) -> (predicate:NSPredicate, dateString:String) {
        let sortedDates = dates.sorted { (date1, date2) -> Bool in
            return date1.int64Value() <= date2.int64Value();
        };
        let calendar = Calendar.current;
        var previousDate = sortedDates.first;
        var index = 1;
        var beginDate = calendar.date(from: previousDate!);
        var endDate:Date? = nil;
        var predicates:[NSPredicate] = [NSPredicate]();
        var dateString = "\(previousDate!.year!)-\(previousDate!.month!)";
        if previousDate!.day != nil {
            dateString += "-\(previousDate!.day!)";
        }
        while index < sortedDates.count{
            let comp = sortedDates[index];
            let preDate = sortedDates[index - 1];
            var isNext:Bool = calendar.dateComponents([.day], from: preDate, to: comp).day! != 1;
            if (interval == .month){
                isNext = calendar.dateComponents([.month], from: preDate, to: comp).month! != 1;
            }
            if (isNext){
                endDate = calendar.date(from: comp);
                dateString += previousDate!.compareWith(preDate) == .orderedSame ? "" : "至\(previousDate!.year!)-\(previousDate!.month!)";
                if previousDate!.day != nil {
                    dateString += "-\(previousDate!.day!)";
                }
                dateString += "\n \(comp.year!)-\(comp.month!)";
                if comp.day != nil {
                    dateString += "-\(comp.day!)";
                }
                let aPredicate = NSPredicate(format: "end > %@ AND end < %@", beginDate! as NSDate, endDate! as NSDate);
                predicates.append(aPredicate);
                previousDate = comp;
                beginDate = calendar.date(from: comp);
            }
            index = index + 1;
        }
        let lastDate = sortedDates.last;
        endDate = calendar.date(from: sortedDates.last!);
        dateString += previousDate!.compareWith(lastDate!) == .orderedSame ? "" : "至\(lastDate!.year!)-\(lastDate!.month!)";
        if lastDate!.day != nil {
            dateString += "-\(lastDate!.day!)";
        }
        let aPredicate = NSPredicate(format: "end > %@ AND end < %@", beginDate! as NSDate, endDate! as NSDate);
        predicates.append(aPredicate);
        
        let predicate = NSCompoundPredicate(orPredicateWithSubpredicates: predicates);
        return (predicate, dateString);
    }
    
    func continuousPredicate(_ dates:[DateComponents],interval:HTimeIntervalType) -> (predicate:NSPredicate, dateString:String) {
        let firstDate = dates.first;
        let lasteDate = dates.last;
        var dateString:String? = nil;
        let calendar = Calendar.current;
        let beginDate = calendar.date(from: firstDate!);
        let endDate = calendar.date(from: lasteDate!)?.startDayDate(after: 1);
        
        let predicate = NSPredicate(format: "end > %@ AND end < %@", beginDate! as NSDate, endDate! as NSDate);
        
        switch interval {
        case .day, .week:
            dateString = "\(firstDate!.year!)-\(firstDate!.month!)-\(firstDate!.day!)至\(lasteDate!.year!)-\(lasteDate!.month!)-\(lasteDate!.day!)";
        case .month:
            dateString = "\(firstDate!.year!)-\(firstDate!.month!)至\(lasteDate!.year!)-\(lasteDate!.month!)";
        }
        return(predicate, dateString!);
    }
    
    func unitPredicate(_ dates:[DateComponents],interval:HTimeIntervalType) -> (predicate:NSPredicate, dateString:String) {
        let firstDate = dates.first;
        let lasteDate = dates.last;
        var predicate:NSPredicate? = nil;
        var dateString:String? = nil;
        switch interval {
        case .day:
            dateString = "\(firstDate!.year!)-\(firstDate!.month!)-\(firstDate!.day!)";
            predicate = NSPredicate(format: "year == \(firstDate!.year!) AND month == \(firstDate!.month!) AND day == \(firstDate!.day!)");
        case .month:
            dateString = "\(firstDate!.year!)-\(firstDate!.month!)";
            predicate = NSPredicate(format: "year == \(firstDate!.year!) AND month == \(firstDate!.month!)");
        case .week:
            let calendar = Calendar.current;
            let beginDate = calendar.date(from: firstDate!);
            let endDate = calendar.date(from: lasteDate!)?.startDayDate(after: 1);
            dateString = "\(firstDate!.year!)-\(firstDate!.month!)-\(firstDate!.day!)至\(firstDate!.year!)-\(firstDate!.month!)-\(firstDate!.day!)";
            predicate = NSPredicate(format: "end > %@ AND end < %@", beginDate! as NSDate, endDate! as NSDate);
        }
        return(predicate!, dateString!);
    }

}
